package com.awenhui.demo.extension;

import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.util.Arrays;
import java.util.Enumeration;

/**
 * @author yuxf
 * @version 1.0
 * @date 2021/1/28 11:31
 */
@Component
@Aspect
@Slf4j
public class SignAspect {
    /**
     * 定义切入点，切入点为com.example.demo.aop.AopController中的所有函数
     * 通过@Pointcut注解声明频繁使用的切点表达式
     */
    @Pointcut("execution(public * com.awenhui.demo.controller..*(..))")
    public void TestAspect() {

    }

    //执行方法前的拦截方法
    @Before("TestAspect()")
    public void doBeforeMethod(JoinPoint joinPoint) {
        System.out.println("@Before...");
        //获取request对象
        ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = requestAttributes.getRequest();
        String requestURI = request.getRequestURI();
        Enumeration<String> parameterNames = request.getParameterNames();
        String remoteAddr = request.getRemoteAddr();

        log.info("IP:{},requestURI:{},parameterNames:{}", remoteAddr, requestURI,parameterNames  );

        //获取目标方法的参数信息
        Object[] obj = joinPoint.getArgs();
        for (Object argItem : obj) {
            System.out.println("---->now-->argItem:" + argItem);
        }
    }

    //执行方法前的拦截方法
    @Before(value = "execution(* com.awenhui.demo.controller..*(..))&&args(name,age)")
    public void doBeforeMethod1(JoinPoint joinPoint, String name, String age) {
        System.out.println("@Before...");
        System.out.println("参数name:" + name + ",参数age:" + age);
        //获取目标方法的参数信息
        Object[] obj = joinPoint.getArgs();
        for (Object argItem : obj) {
            System.out.println("---->now-->argItem:" + argItem);
        }
    }

    @After("execution(public * com.awenhui.demo.controller..*(..))")
    public void doAfterMethod() {
        System.out.println("@After...");
    }

    @AfterReturning(value = "execution(* com.awenhui.demo.controller..*(..))",returning = "result")
    public void doAfterReturningMethod(Object result)
    {
        System.out.println("@AfterReturning..."+result);
    }

    @AfterThrowing("execution(* com.awenhui.demo.controller..*(..))")
    public void doAfterThrowingMethod() {
        System.out.println("@AfterThrowing...");
    }

    //拦截只有一个参数的方法，并传入aop中
    @After("TestAspect()&&args(arg1)")
    public void doAfterMethod1(String arg1) {
        System.out.println("@After...");
    }


    @Around("execution(* com.awenhui.demo.controller..*(..))")
    public Object doAroundMethod(ProceedingJoinPoint pj) throws Throwable {

        System.out.println("@Around aaa ...");
        Object proceed = pj.proceed();
        System.out.println("Around bbb ...");
        return proceed;
    }

}
